package main

import (
	"fmt"
	"net/http"

	"github.com/abbot/go-http-auth"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
	"github.com/satori/go.uuid"
	"strings"
	"bytes"
	"encoding/json"
)

var session *mgo.Session
func init() {
	var err error
	session, err =  mgo.Dial("mongo_1:27017")
	if nil != err {
		panic(fmt.Sprintf("failed to mgo.Dial, cuz %s", err.Error()))
	}
	session.SetMode(mgo.Monotonic, true)
	credential := &mgo.Credential{Username: "root", Password: "d8e1a47a"}
	if err := session.Login(credential); err != nil {
		panic(fmt.Sprintf("failed to mgo.Login, cuz %s", err.Error()))
	}
}

func Secret(user, realm string) string {
	if user == "aite" {
		return "$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1"
	} else {
		return ""
	}
}

func query(tkid string) []interface{}{
	table := session.Clone().DB("scanline").C("scanresult")
	var result []interface{}
	err := table.Find(bson.M{"tkid": tkid}).All(&result)
	if nil != err {
		panic(err)
	}
	return result
}

func task(w http.ResponseWriter, r *auth.AuthenticatedRequest) {

	submit := `<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Bootstrap</title>
  <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">  
  <script src="http://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
  <script src="http://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  <script type="text/javascript">
  </script>
  <style>    
</style> 
</head>
<body>

<!-- 输入框 -->
<div style="padding: 100px 35px 20px;">
  <form class="bs-example bs-example-form" role="form">
    <div class="row">
      <div class="form-inline">
		<form method="post" action="task">
        <p>DOMAIN : <input type="text" class="form-control" name="domain" style="width: 300px">
		<p><input type="submit" value="SUBMIT" /></p>
		</form>
      </div>
    </div>
    <br>
    <br>
  </form>
</div>

</body>
</html>`
	info := `
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Bootstrap</title>
  <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">  
  <script src="http://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script>
  <script src="http://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  <style>    
</style> 
</head>
<body>
<div class="panel-group col-lg-6" id="accordion">

%s

</div>
</body>
</html>
`
	detail := `<div class="panel panel-default">
		<div class="panel-heading">
			<h4 class="panel-title">
				<a data-toggle="collapse" data-parent="#accordion" 
				   href="#collapse%d">
						%s
				</a>
			</h4>
		</div>
		<div id="collapse%d" class="panel-collapse collapse">
			<div class="panel-body">
				%s
			</div>
		</div>
	</div>`

	r.ParseForm()
	if 0 != len(r.Form) {
		domain := r.Form.Get("domain")
		if 0 != len(domain) {
			tkid, _ := uuid.NewV4()
			_, err := http.Post("http://nsqd_1:4151/pub?topic=scanlineep", "json",
				strings.NewReader(fmt.Sprintf(`{"domain":"%s","tkid":"%s"}`, domain, tkid)))
			if nil != err {
				panic(err)
			}
			fmt.Fprintf(w, `<head> <meta http-equiv="refresh" content="5; url=/task?tkid=%s"> </head>`, tkid)
		}
		tkid := r.Form.Get("tkid")
		if 0 != len(tkid) {
			result := query(tkid)
			var buf bytes.Buffer
			for i, e := range result {
				m := e.(bson.M)
				is := m["scan_result"]
				s := is.(bson.M)
				it := s["scan_type"]
				t := it.(string)
				if 0 == len(t) {
					continue
				}
				body, _ := json.Marshal(m)
				var prettyJSON bytes.Buffer
    				json.Indent(&prettyJSON, body, "<br>", "&nbsp;&nbsp;&nbsp;")	
				buf.WriteString(fmt.Sprintf(detail, i, t, i, string(prettyJSON.Bytes())))
			}
			fmt.Fprint(w, fmt.Sprintf(info, buf.String()))
		}
	} else {
		fmt.Fprintf(w, submit)
	}
}

func main() {
	authenticator := auth.NewBasicAuthenticator("127.0.0.1", Secret)
	http.HandleFunc("/task", authenticator.Wrap(task))
	http.ListenAndServe(":8123", nil)
}
